package main

import (
	"fmt"
	"math"
	"strings"
	"unsafe"
)

func main() {
	fmt.Println("0 BinFormat:    ", BinaryFormat(0))
	fmt.Println("1 BinFormat:    ", BinaryFormat(1))
	fmt.Println("-1 BinFormat:   ", BinaryFormat(-1))
	fmt.Println("260 BinFormat:  ", BinaryFormat(260))
	fmt.Println("-260 BinFormat: ", BinaryFormat(-260))
}

func BinaryFormat(n int32) string {
	a := uint32(n)          // 先把 int32 转换为无符号的 uint32，用于跟 uint32 最大值位逐个对比匹配。
	sb := strings.Builder{} // 初始化一个字符串方法来存储匹配的位
	c := uint32(math.Pow(2, 31))
	for i := 0; i < 32; i++ {
		if a&c != 0 { // 位运算，匹配就是 1 ，不匹配就是 0
			sb.WriteString("1")
		} else {
			sb.WriteString("0")
		}
		c >>= 1 // 每匹配一次，最大值位就右移一次，直到完尽
	}
	return sb.String() // 返回最终结果
}

//  Job End Line

func _() {
	// intDemo
	// uintX 的区别是在内存中的长度是不一样
	var a uint
	var b uint8
	var c uint16 = 100
	var d uint32
	var e uint64
	// unsafe.Sizeof() 只返回数据类型的大小，不管引用数据的大小，单位为 Byte
	fmt.Println("size of: ", unsafe.Sizeof(a)) // 8
	fmt.Println("size of: ", unsafe.Sizeof(b)) // 1
	fmt.Println("size of: ", unsafe.Sizeof(c)) // 2
	fmt.Println("size of: ", unsafe.Sizeof(d)) // 4
	fmt.Println("size of: ", unsafe.Sizeof(e)) // 8 在32位系统中uint和uint32相同，在64位系统中uint和uint64位相同
	// uintX 与 intX 的区别在于是否有符号，也就是是否能支持负数，uint 不支持负数。
	// 实际用途中选哪一个取决于预期的范围
	// int8: -128 ~ 127
	// int16: -32768 ~ 32767
	// int32: -2147483648 ~ 2147483647
	// int64: -9223372036854775808 ~ 9223372036854775807
	// uint8: 0 ~ 255
	// uint16: 0 ~ 65535
	// uint32: 0 ~ 4294967295
	// uint64: 0 ~ 18446744073709551615
}

func _() {
	// string.Builder{} 通过 slice 存储，通过 WriteString 的写入方法来写入内容，然后通过调用 String() 方法来获取拼接的字符串.
	a := strings.Builder{}
	a.WriteString("1") // 调用写入方法的时候，新的字节数据就被追加到 slice 上
	a.WriteString("hi")
	a.WriteString("0")
	fmt.Println(a.String()) // 1hi0
}
